import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:sudoku/util/app_util.dart';
import 'package:sudoku/util/global.dart';
import 'package:sudoku/util/image_util.dart';
import 'package:sudoku/util/sukodu/generator.dart';
import 'package:sudoku/util/sukodu/tools.dart';
import 'package:sudoku/viewModel/GameViewModel.dart';
import 'package:sudoku/widget/MenuButton.dart';
import '../util/widget_util.dart';

class GamePage extends StatelessWidget {
  final LEVEL level;
  final GameViewModel _viewModel;

  GamePage(this.level) : _viewModel = Get.put(GameViewModel(level));

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          commonBackground(),
          Scaffold(
            appBar: AppBar(
              title: Text(LEVEL_TITLE[level]!),
            ),
            body: SafeArea(
              child: Column(
                children: [
                  Obx(() => Text(
                        durationStr(_viewModel.countDownNum.value),
                        style: const TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontFamily: "Han",
                            fontSize: 30),
                      )),
                  _headerWidget(),
                  const SizedBox(
                    height: 10,
                  ),
                  Obx(() => GridView.builder(
                      physics: const NeverScrollableScrollPhysics(),
                      shrinkWrap: true,
                      itemCount: _viewModel.puzzles.length,
                      gridDelegate:
                          const SliverGridDelegateWithFixedCrossAxisCount(
                              crossAxisCount: 9),
                      itemBuilder: ((BuildContext context, int index) {
                        onTap() {
                          _viewModel.chooseBoxIndex.value = index;
                        }

                        return _gridInWellWidget(
                            context, index, _viewModel.puzzles[index], onTap);
                      }))),
                  const Spacer(),
                  _operateWidget()
                ],
              ),
            ),
          )
        ],
      ),
    );
  }

  Widget _headerWidget() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          MenuButton(onPressed: _viewModel.resetClick, title: "重置"),
          MenuButton(onPressed: _viewModel.pauseClick, title: "暂停"),
        ],
      ),
    );
  }

  Widget _gridInWellWidget(
      BuildContext context, int index, int num, VoidCallback onTap) {
    return InkWell(
      highlightColor: Colors.blue,
      customBorder: Border.all(color: Colors.blue),
      onTap: onTap,
      child: Obx(() => Container(
            alignment: Alignment.center,
            margin: const EdgeInsets.all(1),
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(5),
                color: _gridInWellBgColor(index)),
            child: Text('${num == -1 ? '' : num}',
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontSize: 25,
                    fontWeight: FontWeight.w800,
                    color: _viewModel.isCorrect(index)
                        ? Colors.white
                        : Colors.red)),
          )),
    );
  }

  /// 计算网格背景色
  Color _gridInWellBgColor(int index) {
    Color gridWellBackgroundColor;
    // 同宫
    List<int> zoneIndexes =
        Matrix.getZoneIndexes(zone: Matrix.getZone(index: index));
    // 同行
    List<int> rowIndexes = Matrix.getRowIndexes(Matrix.getRow(index));
    // 同列
    List<int> colIndexes = Matrix.getColIndexes(Matrix.getCol(index));

    Set indexSet = {};
    indexSet.addAll(zoneIndexes);
    indexSet.addAll(rowIndexes);
    indexSet.addAll(colIndexes);

    if (index == _viewModel.chooseBoxIndex.value) {
      gridWellBackgroundColor = const Color.fromARGB(255, 0x70, 0xF3, 0xFF);
    } else if (indexSet.contains(_viewModel.chooseBoxIndex.value)) {
      gridWellBackgroundColor = const Color.fromARGB(255, 0x44, 0xCE, 0xF6);
    } else {
      if (Matrix.getZone(index: index).isOdd) {
        gridWellBackgroundColor = gradientPurple;
      } else {
        gridWellBackgroundColor = gradientBlue;
      }
    }
    return gridWellBackgroundColor;
  }

  Widget _operateWidget() {
    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 5),
          child: Row(
            children: List.generate(9, (index) => _numWidget(index)).toList(),
          ),
        ),
        const SizedBox(
          height: 25,
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Row(
              children: [
                InkWell(
                  onTap: _viewModel.remindClick,
                  child: loadAssetImage("help_hint", width: Get.width * 0.15),
                ),
                const SizedBox(
                  width: 5,
                ),
                Obx(() => Text(
                      "x${_viewModel.remindNum.value}",
                      style: const TextStyle(
                          color: Colors.white, fontFamily: "Han", fontSize: 30),
                    ))
              ],
            ),
            InkWell(
              onTap: _viewModel.clearItem,
              child: loadAssetImage("del_note", width: Get.width * 0.15),
            ),
          ],
        ),
      ],
    );
  }

  Widget _numWidget(int num) {
    double itemWH = ((Get.width - 10 * 10) / 9.0).floorToDouble();
    return Stack(
      children: [
        GestureDetector(
          onTap: () {
            _viewModel.fillBox(num + 1);
          },
          child: Container(
            width: itemWH,
            height: itemWH,
            margin: const EdgeInsets.symmetric(horizontal: 5),
            child: Stack(
              alignment: Alignment.center,
              children: [
                loadAssetImage("num_bg"),
                Text(
                  "${num + 1}",
                  style: const TextStyle(
                      fontWeight: FontWeight.w700,
                      fontSize: 18,
                      fontFamily: "Han"),
                )
              ],
            ),
          ),
        )
      ],
    );
  }
}
